﻿using DG.Tweening;
using System;
using TMPro;
using UniRx;
using UnityEngine;

public class FloatDamageNumber : USaBehaviour
{
    [SerializeField]
    private TextMeshPro m_NumberLabel;

    private const string PREFAB_ROOT_PATH = "FloatDamageNumbers/{0}.prefab";
    private const string PREFAB_KEY = "FloatDamageNumber";
    private static AssetCache<string, GameObject> s_PrefabCaches = new AssetCache<string, GameObject>(PREFAB_ROOT_PATH);
    private static ObjectPool<FloatDamageNumber> s_Pool;
    private static IDisposable s_CleanPoolListener = null;

    private Timer.DoubleStage m_Timer = new Timer.DoubleStage();

    /// <summary>
    /// 生成特效
    /// </summary>
    public static async void Spawn(double damage, UnitEntityBase entity)
    {
        if (s_CleanPoolListener == null)
        {
            s_CleanPoolListener = SceneManager.onLoadingMaskEnabled.Subscribe(_ => s_Pool?.Clear());
        }
        if (s_Pool == null)
        {
            var prefab = await s_PrefabCaches.LoadAsync(PREFAB_KEY);
            s_Pool = new ObjectPool<FloatDamageNumber>(prefab);
        }
        var fdn = s_Pool.Rent();
        fdn.SetData(damage);
        var fdnTrans = fdn.gameObject.transform;
        var point = (Vector2)entity.transform.position + entity.physics.box.size * Vector2.up + Vector2.up * 0.5f;
        fdnTrans.position = point;
        fdnTrans.parent = SceneOrganizer.instance.transform.parent;
        fdnTrans.SetAsLastSibling();
    }

    private void Awake()
    {
        m_Timer.onStart.Subscribe(_ =>
        {
            m_NumberLabel.DOKill();
            m_NumberLabel.alpha = 1;
            m_NumberLabel.transform.DOKill();
            m_NumberLabel.transform.localPosition = Vector3.zero;
            m_NumberLabel.transform.DOLocalMoveY(0.5f, 2f).SetEase(Ease.Linear);
        });
        m_Timer.onFinish_1.Subscribe(_ =>
        {
            m_NumberLabel.DOFade(0, 0.5f).SetEase(Ease.Linear);
        });
        m_Timer.onFinish_2.Subscribe(_ =>
        {
            s_Pool.Return(this);
        });
        m_Timer.onShutDown.Subscribe(_ =>
        {
            m_NumberLabel.DOKill();
            m_NumberLabel.transform.DOKill();
        });
    }

    private void OnEnable()
    {
        m_Timer.Start(0.6f, 0.4f, this);
    }

    private void OnDestroy()
    {
        m_Timer.ShutDown();
    }

    public void SetData(double number)
    {
        m_NumberLabel.text = number.ToString("0");
    }
}